package br.com.felix.fwt.util;

import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.log4j.Logger;

import br.com.felix.fwt.log.LoggerFactory;
import br.com.felix.fwt.util.exception.ImageGenerationException;

import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class Thumbnail {

    private static final Logger logger = LoggerFactory.getLogger(Thumbnail.class);
    
    /**
     * Creates a thumbnail for the informed image data at the thumbnail file.
     * */
    public static void createThumbnail(byte[] imagedata, File thumbnail, int thumbWidth, int thumbHeight) throws ImageGenerationException  {
    	Image img = Toolkit.getDefaultToolkit().createImage(imagedata);
    	createThumbnail(img, thumbnail, thumbWidth, thumbHeight);
    }
    
    
    /**
     * Creates a thumbnail for the informed image at the thumbnail file.
     * */
    public static void createThumbnail(Image img, File thumbnail, int thumbWidth, int thumbHeight) throws ImageGenerationException  {
    	MediaTracker mediaTracker = new MediaTracker(new Container());
        mediaTracker.addImage(img, 0);
        try {
            mediaTracker.waitForID(0);
        }
        catch (InterruptedException e) {
            String msg = "Error generating thumbnail. MediaTracker interrupted.";
            logger.error(msg, e);
            throw new ImageGenerationException(msg, e);
        }
        double thumbRatio = (double) thumbWidth / (double) thumbHeight;
        int imageWidth = img.getWidth(null);
        int imageHeight = img.getHeight(null);
        double imageRatio = (double) imageWidth / (double) imageHeight;
        if (thumbRatio < imageRatio) {
            thumbHeight = (int) (thumbWidth / imageRatio);
        }
        else {
            thumbWidth = (int) (thumbHeight * imageRatio);
        }
        BufferedImage thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics2D = thumbImage.createGraphics();
        graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        graphics2D.drawImage(img, 0, 0, thumbWidth, thumbHeight, null);
        BufferedOutputStream out;
        try {
            out = new BufferedOutputStream(new FileOutputStream(thumbnail));
        }
        catch (FileNotFoundException e) {
            String msg = "Error generating thumbnail. Thumbnail's parent folder does not exist.";
            logger.error(msg, e);
            throw new ImageGenerationException(msg, e);
        }
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(thumbImage);
        int quality = 100;
        param.setQuality((float) quality / 100.0f, false);
        encoder.setJPEGEncodeParam(param);
        try {
            encoder.encode(thumbImage);
            out.close();
            logger.info("Generated thumbnail '" + thumbnail.getAbsolutePath()+"'.");
        }
        catch (ImageFormatException e) {
            String msg = "Error generating thumbnail. An ImageFormatException ocurred while encoding JPG.";
            logger.error(msg, e);
            throw new ImageGenerationException(msg, e);
        }
        catch (IOException e) {
            String msg = "Error generating thumbnail. An IOException ocurred while encoding JPG.";
            logger.error(msg, e);
            throw new ImageGenerationException(msg, e);
        }
    }
    
    
    /**
     * Creates a thumbnail for the informed image at the thumbnail file.
     * */
    public static void createThumbnail(File image, File thumbnail, int thumbWidth, int thumbHeight) throws ImageGenerationException  {
        Image img = Toolkit.getDefaultToolkit().getImage(image.getAbsolutePath());
        createThumbnail(img, thumbnail, thumbWidth, thumbHeight);
    }
}
